package MiGong;

import java.util.Random;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;

public class MiGongPlus {
    public static void main(String[] args) {
        System.out.println("-----迷宫游戏-----");
        String[][] arr = creatMiGong();
        Player p = new Player();
        Scanner sc = new Scanner(System.in);

        while (true) {
            printStr(arr);
            System.out.println("玩家状态 - 生命:" + p.getHp() + " 攻击:" + p.getAttack() + " 防御:" + p.getDefense() + " 速度:" + p.getSpeed());
            move(arr, p, sc);
            if (p.getHp() <= 0) {
                System.out.println("生命值耗尽，游戏结束！");
                return;
            }
        }
    }

    public static String[][] creatMiGong() {
        String[][] arr = new String[8][8];
        Random r = new Random();
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                if (i == 0 && j == 0) {
                    arr[i][j] = "P";
                    continue;
                }
                if (i == 7 && j == 7) {
                    arr[i][j] = "Out";
                    continue;
                }
                int x = r.nextInt(10);
                if (x < 2) {
                    arr[i][j] = "|";
                } else if (x < 4) {
                    arr[i][j] = r.nextBoolean() ? "W" : "A";
                } else if (x == 4) {
                    arr[i][j] = "T";
                } else if (x < 8) {
                    arr[i][j] = "M";
                } else if (x == 8) {
                    arr[i][j] = "shijian";
                } else {
                    arr[i][j] = "skill";
                }
            }
        }
        return arr;
    }

    public static void printStr(String[][] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                if (arr[i][j].equals("|") || arr[i][j].equals("P") || arr[i][j].equals("Out")) {
                    System.out.print(arr[i][j] + " ");
                } else {
                    System.out.print("_ ");
                }
            }
            System.out.println();
        }
    }

    public static void move(String[][] arr, Player p, Scanner sc) {
        int[] position = findPlayer(arr);
        int hang = position[0], lie = position[1];

        System.out.print("请输入移动方向(w/a/s/d): ");
        String input = sc.nextLine().trim().toLowerCase();
        int newHang = hang, newLie = lie;

        switch (input) {
            case "w": newHang--; break;
            case "a": newLie--; break;
            case "s": newHang++; break;
            case "d": newLie++; break;
            default:
                System.out.println("无效输入!");
                return;
        }

        if (!isValidMove(arr, newHang, newLie)) {
            System.out.println("无法移动!");
            return;
        }

        handleEvent(arr, hang, lie, newHang, newLie, p);
    }

    private static int[] findPlayer(String[][] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                if (arr[i][j].equals("P")) {
                    return new int[]{i, j};
                }
            }
        }
        return new int[]{0, 0};
    }

    private static boolean isValidMove(String[][] arr, int newHang, int newLie) {
        if (newHang < 0 || newHang >= 8 || newLie < 0 || newLie >= 8) return false;
        return !arr[newHang][newLie].equals("|");
    }

    private static void handleEvent(String[][] arr, int oldHang, int oldLie, int newHang, int newLie, Player p) {
        String event = arr[newHang][newLie];
        arr[oldHang][oldLie] = "_";
        arr[newHang][newLie] = "P";

        if (p.getInvulnerableSteps() > 0) {
            p.decreaseInvulnerableSteps();
            System.out.println("当前处于免疫状态，剩余步数: " + p.getInvulnerableSteps());
        }

        switch (event) {
            case "W":
                Weapon weapon = generateWeapon(newHang, newLie);
                handleWeapon(p, weapon);
                break;
            case "A":
                Armor armor = generateArmor(newHang, newLie);
                handleArmor(p, armor);
                break;
            case "T":
                p.setHp(Math.min(p.getHp() + 20, 100));
                System.out.println("使用道具! 生命+20");
                break;
            case "M":
                if (p.getInvulnerableSteps() > 0) {
                    System.out.println("当前处于免疫状态，不会受到怪物攻击");
                    break;
                }
                Monster monster = generateMonster(newHang, newLie);
                if (!fightMonster(p, monster)) {
                    System.out.println("你被" + monster.getName() + "击败了！");
                    System.exit(0);
                }
                break;
            case "shijian":
                shiJian(arr, p);
                break;
            case "skill":
                Skill skill = generateSkill();
                p.addSkill(skill);
                break;
            case "Out":
                System.out.println("成功逃出迷宫！");
                System.exit(0);
        }
    }

    private static Weapon generateWeapon(int hang, int lie) {
        Random r = new Random();
        List<Weapon> availableWeapons = new ArrayList<>();
        boolean isLateArea = (hang + lie) >= 8;

        availableWeapons.add(new Weapon("木剑", 10));
        availableWeapons.add(new Weapon("铁剑", 20));
        availableWeapons.add(new Weapon("钻石剑", 50));

        if (isLateArea) {
            int rand = r.nextInt(3);
            return availableWeapons.get(rand);
        } else {
            int rand = r.nextInt(2);
            return availableWeapons.get(rand);
        }
    }

    private static Armor generateArmor(int hang, int lie) {
        Random r = new Random();
        List<Armor> availableArmors = new ArrayList<>();
        boolean isLateArea = (hang + lie) >= 8;

        availableArmors.add(new Armor("木盔甲", 10));
        availableArmors.add(new Armor("铁盔甲", 20));
        availableArmors.add(new Armor("钻石甲", 50));

        if (isLateArea) {
            int rand = r.nextInt(3);
            return availableArmors.get(rand);
        } else {
            int rand = r.nextInt(2);
            return availableArmors.get(rand);
        }
    }

    private static void handleWeapon(Player p, Weapon weapon) {
        if (p.getCurrentWeapon() == null) {
            p.setCurrentWeapon(weapon);
            p.setAttack(p.getAttack() + weapon.getAttack());
            System.out.println("装备了 " + weapon.getName() + "，攻击力提升至 " + p.getAttack());
        } else {
            if (weapon.getAttack() > p.getCurrentWeapon().getAttack()) {
                p.setAttack(p.getAttack() - p.getCurrentWeapon().getAttack() + weapon.getAttack());
                p.setCurrentWeapon(weapon);
                System.out.println("获得新武器: " + weapon.getName() + "，攻击力提升至 " + p.getAttack());
            } else {
                System.out.println("获得武器: " + weapon.getName() + "，但攻击力不如当前武器，已丢弃");
            }
        }
    }

    private static void handleArmor(Player p, Armor armor) {
        if (p.getCurrentArmor() == null) {
            p.setCurrentArmor(armor);
            p.setDefense(p.getDefense() + armor.getDefense());
            System.out.println("装备了 " + armor.getName() + "，防御力提升至 " + p.getDefense());
        } else {
            if (armor.getDefense() > p.getCurrentArmor().getDefense()) {
                p.setDefense(p.getDefense() - p.getCurrentArmor().getDefense() + armor.getDefense());
                p.setCurrentArmor(armor);
                System.out.println("获得新防具: " + armor.getName() + "，防御力提升至 " + p.getDefense());
            } else {
                System.out.println("获得防具: " + armor.getName() + "，但防御力不如当前防具，已丢弃");
            }
        }
    }

    private static Monster generateMonster(int hang, int lie) {
        Random r = new Random();
        List<Monster> availableMonsters = new ArrayList<>();
        availableMonsters.add(new Monster("小白", 80, 20, 50));
        availableMonsters.add(new Monster("僵尸", 120, 10, 65));

        boolean isLateArea = (hang >= 4 && lie >= 4);

        if (isLateArea) {
            availableMonsters.add(new Monster("苦力怕", 150, 100, 1));
            availableMonsters.add(new Monster("小黑", 200, 50, 50));
            availableMonsters.add(new Monster("末影龙", 100, 100, 200));

            int currentSum = hang + lie;
            int minSum = 8;
            int maxSum = 14;
            int weight = currentSum - minSum;

            int totalWeight = 2 * (maxSum - currentSum) + 3 * weight;
            if (totalWeight <= 0) {
                totalWeight = 1;
            }

            int rand = r.nextInt(totalWeight);

            if (rand < 2 * (maxSum - currentSum)) {
                int which = r.nextInt(2);
                return availableMonsters.get(which);
            } else {
                int which = r.nextInt(3);
                return availableMonsters.get(2 + which);
            }
        } else {
            int which = r.nextInt(availableMonsters.size());
            return availableMonsters.get(which);
        }
    }

    private static boolean fightMonster(Player p, Monster monster) {
        int monsterHp = monster.getBlood();
        int monsterAttack = monster.getAttack();
        int monsterSpeed = monster.getSpeed();
        Scanner sc = new Scanner(System.in);
        boolean playerFirst = p.getSpeed() >= monsterSpeed;

        System.out.println("遭遇" + monster.getName() + "! 生命:" + monsterHp + " 攻击:" + monsterAttack + " 速度:" + monsterSpeed);

        while (true) {
            System.out.println("请选择行动: 1. 攻击 2. 使用技能 3. 逃跑");
            String choice = sc.nextLine();

            switch (choice) {
                case "1":
                    monsterHp -= p.getAttack();
                    System.out.println("你造成 " + p.getAttack() + " 伤害");
                    if (monsterHp <= 0) {
                        System.out.println("击败" + monster.getName() + "!");
                        return true;
                    }
                    break;
                case "2":
                    System.out.println("可用技能:");
                    List<Skill> skills = p.getSkills();
                    for (int i = 0; i < skills.size(); i++) {
                        System.out.println((i + 1) + ". " + skills.get(i).getName() + " (数量: " + p.getSkillCount(skills.get(i)) + ")");
                    }
                    System.out.print("选择技能编号（输入 q 或 退出 可取消）: ");
                    String skillInput = sc.nextLine();
                    if (skillInput.equalsIgnoreCase("q") || skillInput.equals("退出")) {
                        System.out.println("取消使用技能");
                        break;
                    }
                    try {
                        int skillIndex = Integer.parseInt(skillInput) - 1;
                        if (skillIndex >= 0 && skillIndex < skills.size()) {
                            Skill selectedSkill = skills.get(skillIndex);
                            if (selectedSkill.getName().equals("葵花宝典")) {
                                System.out.println("使用葵花宝典会扣除你50%的生命值，是否确认使用？(y/n)");
                                String confirm = sc.nextLine();
                                if (!confirm.equalsIgnoreCase("y")) {
                                    System.out.println("取消使用技能");
                                    continue;
                                }
                                p.setHp((int) (p.getHp() * 0.5));
                                System.out.println("你的生命值减少50%，当前生命值: " + p.getHp());
                            }
                            p.useSkill(selectedSkill, monster);
                            if (selectedSkill.getEffectType().equals("attack")) {
                                monsterHp -= selectedSkill.getDamage();
                                System.out.println("你造成 " + selectedSkill.getDamage() + " 伤害");
                                if (monsterHp <= 0) {
                                    System.out.println("击败" + monster.getName() + "!");
                                    return true;
                                }
                            }
                            p.removeSkill(selectedSkill);
                        } else {
                            System.out.println("无效的技能选择");
                            continue;
                        }
                    } catch (NumberFormatException e) {
                        System.out.println("无效的输入，请输入数字或 q/退出");
                        continue;
                    }
                    break;
                case "3":
                    if (p.getSpeed() > monsterSpeed) {
                        System.out.println("成功逃脱!");
                        return true;
                    } else {
                        System.out.println("逃跑失败，浪费了一个回合");
                        int damage = calculateDamage(monsterAttack, p.getDefense());
                        p.setHp(p.getHp() - damage);
                        System.out.println(monster.getName() + " 造成 " + damage + " 伤害，剩余生命:" + p.getHp());
                        if (p.getHp() <= 0) {
                            return false;
                        }
                    }
                    break;
                default:
                    System.out.println("无效的选择");
                    continue;
            }

            int damage = calculateDamage(monsterAttack, p.getDefense());
            p.setHp(p.getHp() - damage);
            System.out.println(monster.getName() + " 造成 " + damage + " 伤害，剩余生命:" + p.getHp());
            if (p.getHp() <= 0) {
                return false;
            }
        }
    }

    private static int calculateDamage(int attack, int defense) {
        double reductionPercentage = Math.min(0.85, 0.20 + (defense * 0.01));
        double actualDamage = attack * (1 - reductionPercentage);
        return (int) Math.max(1, actualDamage);
    }

    private static void shiJian(String[][] arr, Player p) {
        Random r = new Random();
        int i = r.nextInt(3);
        switch (i) {
            case 0:
                int s = r.nextInt(100);
                System.out.println("善良的村民为你送来了加速药水，速度加" + s);
                p.setSpeed(p.getSpeed() + s);
                break;
            case 1:
                p.setInvulnerableSteps(5);
                System.out.println("女巫不忍心看你受到折磨，后面5步内不会有怪物骚扰你了");
                break;
            case 2:
                teleportPlayer(arr, p);
                System.out.println("him似乎不想让你过于顺利，你将被传送到全场任意位置");
                break;
        }
    }

    private static void teleportPlayer(String[][] arr, Player p) {
        Random r = new Random();
        int newHang, newLie;
        do {
            newHang = r.nextInt(8);
            newLie = r.nextInt(8);
        } while (arr[newHang][newLie].equals("|") || arr[newHang][newLie].equals("Out"));

        int[] currentPosition = findPlayer(arr);
        arr[currentPosition[0]][currentPosition[1]] = "_";
        arr[newHang][newLie] = "P";
        p.setHang(newHang);
        p.setLie(newLie);
    }

    private static Skill generateSkill() {
        Random r = new Random();
        List<Skill> availableSkills = new ArrayList<>();
        availableSkills.add(new Skill("金钟罩(本次战斗收到伤害减免40%)", "damageReduction", 0, 0, 0.4, false));
        availableSkills.add(new Skill("葵花宝典(造成100伤害但是损失50%hp)", "attack", 100, 0, 0, true));
        int rand = r.nextInt(availableSkills.size());
        return availableSkills.get(rand);
    }
}